package com.superquan.selfstudybootmybatis.utils.deeporshallowclone;

import com.alibaba.fastjson.JSON;
import com.superquan.selfstudybootmybatis.entity.user.People;
import com.superquan.selfstudybootmybatis.entity.user.SuperClass;
import org.springframework.beans.BeanUtils;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 深拷贝：被复制对象的所有变量都含有与原来的对象相同的值，除去那些引用其他对象的变量；
 * 那些引用其他对象的变量将指向被复制过的新对象，而不再是原有的那些被引用的对象；
 * 换言之，深复制把要复制的对象所引用的对象都复制了一遍
 */
public class ShallowClone {
    public static void main(String[] args) throws IllegalAccessException, InvocationTargetException {

        // 测试数组的复制
        People[] member = new People[4];
        member[0] = new People(1, "teacher", 30, 1);
        member[1] = new People(2, "monitor", 15, 1);
        member[2] = new People(3, "student", 15, 1);
        member[3] = new People(4, "beautifulGirl", 18, 0);
        People[] member1 = new People[]{};
        BeanUtils.copyProperties(member, member1);
        System.out.println("BeanUtils.copyProperties是否可以复制数组：" + (member1.length == 0 ? false : true));

        // 测试List的复制（Map也不能复制，测试略）
        List<People> student = new ArrayList<>();
        student.add(member[1]);
        student.add(member[2]);
        List<People> student1 = new ArrayList<>();
        BeanUtils.copyProperties(student, student1);
        System.out.println("BeanUtils.copyProperties是否可以复制List：" + (student1.isEmpty() ? false : true));

        // 通过JSON工具实现List的复制（不仅仅是List，数组和Map等也可以通过类似方法实现复制，需要有无参构造方法，否则报错）
        student1 = JSON.parseArray(JSON.toJSONString(student), People.class);
        System.out.println("通过JSON工具复制List：" + student1);
//        student.remove(0);
        System.out.println("student:"+student);
        System.out.println("通过JSON工具是否深复制：" + (student.get(0) != student1.get(0) ? true : false));

        // 测试是否深复制
        SuperClass source = new SuperClass();
        source.setMember(member);
        source.setTeacher(member[0]);
        source.setStudent(student);
        SuperClass target = new SuperClass();
        BeanUtils.copyProperties(source, target);
        source.setTeacher(member[3]);
        System.out.println("BeanUtils.copyProperties是否深复制：" + (source.getMember() != target.getMember() ? true : false));

        //使用“=”或putAll实现map的浅拷贝
        Map<String,Object> map1 = new HashMap();
        map1.put("name","harry potter");
        map1.put("address","china");
        Map map2=new HashMap();
//        map2=map1;
        map2.putAll(map1);
        map1.remove("name");
        System.out.println("使用浅拷贝复制后map2:"+map2.toString());

        //HashMap调用putAll()使用深拷贝
        HashMap hashMap1 = new HashMap();
        hashMap1.put("name", "Mary");
        hashMap1.put("address","Chicago");
        HashMap hashMap2 = new HashMap();
        hashMap2.putAll(hashMap1);
        hashMap1.remove("name");
        System.out.println("HashMap使用深拷贝复制后hashMap2:"+hashMap2.toString());
    }
}
